package app;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import org.apache.log4j.PropertyConfigurator;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.logging.LogLevel;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import coder.ServerDecoder;
import coder.ServerEncoder;
import config.ServerConfig;
import core.LogicThread;
import sql.SqlManager;
import system.AbstractSystem;
import system.LoginSystem;
import system.SynchronizationSystem;

public class ServerApplication 
{

	public static Map<Integer, AbstractSystem> systems = new HashMap<Integer, AbstractSystem>();
	
	private static final Logger logger = LoggerFactory.getLogger(ServerApplication.class); 
	
	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{
		 PropertyConfigurator.configure("config/log4j.properties");  
		 logger.debug("init logger ok!");
		 if(!ServerConfig.initConfig())
		 {
			 logger.warn("Loading ServerCofnig error!!!");
			 return;
		 }
		 //策略服
		 if(ServerConfig.getValue("isTactics") == "true")
		 {
			 //启动策略服
			 startTactics();
		 }
		 
		 //初始化数据库   查询玩家数据
//		 if(SqlManager.getInstance().connect())
//		 {
//			 logger.debug("init database ok!");
//			 try 
//			 {
//				SqlManager.getInstance().loadingUserInfo();
//			 } 
//			 catch (SQLException e) 
//			 {
//				logger.error("Loading userInfo error!!!" + e.getMessage());
//			 }
//		 }			 
//		 else 
//		 {
//			 logger.error("init database error!");
//			 System.exit(0);
//		 }
		 startNetWork();
		 //初始化所有的系统
		 initSystems();
		 //开启逻辑线程
		 Thread logic = new LogicThread();
		 logic.start();
		 logger.debug("Logic Thread started!");
	}
	
	private static void startNetWork()
	{
		NioSocketAcceptor acceptor = new NioSocketAcceptor();
		Executor threadPool = Executors.newFixedThreadPool(5);
		acceptor.getFilterChain().addLast("exector", new ExecutorFilter(threadPool));
		acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ServerEncoder(), new ServerDecoder())); 
		
		LoggingFilter filter = new LoggingFilter();
	    filter.setExceptionCaughtLogLevel(LogLevel.ERROR);  
	    filter.setSessionClosedLogLevel(LogLevel.INFO);  
	    filter.setSessionCreatedLogLevel(LogLevel.INFO);  
	    filter.setSessionOpenedLogLevel(LogLevel.INFO);  
	    acceptor.getFilterChain().addLast("logger", filter);   
		
		//设置为非延迟发送，为true则不组装成大包发送，收到东西马上发出 
		acceptor.getSessionConfig().setTcpNoDelay(true); 
		acceptor.setDefaultLocalAddress(new InetSocketAddress(Integer.parseInt(ServerConfig.getValue("port"))));
		acceptor.setHandler(new ServerHandler());  
	    try 
	    {
			acceptor.bind();
		} 
	    catch (IOException e) 
	    {
	    	logger.error("ServerSocker bind error!!!!!!\n  application will Shutdown!");
	    	System.exit(0);
		}  
	}
	
	/**
	 * 启动策略服
	 */
	private static void startTactics()
	{
		
	}
	
	private static void initSystems() 
	{
		new SynchronizationSystem();
		new LoginSystem();
		Iterator<AbstractSystem> iter = systems.values().iterator();
		while(iter.hasNext())
		{
			AbstractSystem stm = iter.next();
			if(!stm.init())//系统初始化出错
			{
				logger.error(stm.getClass().getName() + "   init error!!!");
				System.exit(0);
			}
		}
	}
	
}
